package top.zk123.chain.service;

import org.springframework.web.multipart.MultipartFile;
import top.zk123.chain.bean.Certificate;
import top.zk123.chain.bean.CertificateTmp;
import top.zk123.chain.bean.ReturnInfo;
import top.zk123.chain.bean.UploadPath;
import top.zk123.chain.bean.returnObj.CertOnChain;
import top.zk123.chain.exception.*;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

/**
 * 证书相关 业务逻辑层
 *
 * @author Ke Zhang
 * @since 1.0
 */
public interface CertificateService {
    /**
     * 上传 Excel 文件.
     *
     * @param file Excel 文件
     * @return ReturnInfo
     * @throws WrongFileTypeException 不支持的文件类型
     * @throws FileEmptyException     文件为空
     * @throws FileUploadException    文件上传失败
     * @throws EmptyStringException   无后缀
     */
    ReturnInfo uploadExcel(MultipartFile file) throws
            WrongFileTypeException, FileEmptyException, FileUploadException, EmptyStringException;

    /**
     * 多图片上传
     *
     * @param files           多文件
     * @param imgUploadFolder 文件上传路径
     * @return ReturnInfo
     * @throws WrongFileTypeException 不支持的文件类型
     * @throws FileEmptyException     文件为空
     * @throws FileUploadException    文件上传失败
     * @throws EmptyStringException   无后缀
     */
    ReturnInfo uploadImages(MultipartFile[] files, String imgUploadFolder) throws
            FileUploadException, WrongFileTypeException, FileEmptyException, EmptyStringException;

    /**
     * 上传证书信息
     *
     * @param certificate 证书
     * @return ReturnInfo
     */
    ReturnInfo uploadSingleCert(Certificate certificate);

    /**
     * 上传多张证书, 解析完毕后,存储在 CertificateTmp 数据库中
     *
     * @param excel   excel 文件
     * @param userPic 一寸照（批量）
     * @param certPic 证书扫描件（批量）
     * @return ReturnInfo
     * @throws FileUploadException               文件上传失败
     * @throws WrongFileTypeException            不支持的文件类型
     * @throws FileEmptyException                文件为空
     * @throws EmptyStringException              后缀为空
     * @throws ExcelNotFoundException            Excel不存在
     * @throws ExcelParseErrorException          Excel解析失败
     * @throws ExcelDataLinkToPicFailedException Excel解析数据与图片不符
     */
    ReturnInfo parseMultipleCert(MultipartFile excel, MultipartFile[] userPic, MultipartFile[] certPic)
            throws FileUploadException, WrongFileTypeException, FileEmptyException, EmptyStringException,
            ExcelNotFoundException, ExcelParseErrorException, ExcelDataLinkToPicFailedException;


    /**
     * 根据 InstitutionId 从 CertificateTmp 数据库中, 将对应的记录移储至 Certificate 数据库
     *
     * @return ReturnInfo
     * @throws InvocationTargetException .
     * @throws IllegalAccessException    .
     */
    ReturnInfo saveMultipleCert() throws InvocationTargetException, IllegalAccessException;

    /**
     * 上传图片
     *
     * @param files           图片
     * @param imgUploadFolder 图片路径  "userPic\\"
     * @return List {@link UploadPath}
     * @throws FileUploadException    文件上传失败
     * @throws WrongFileTypeException 不支持的文件类型
     * @throws FileEmptyException     文件为空
     * @throws EmptyStringException   文件后缀为空
     */
    List<UploadPath> uploadImagesAndGetPath(MultipartFile[] files, String imgUploadFolder) throws
            FileUploadException, WrongFileTypeException, FileEmptyException, EmptyStringException;

    /**
     * 获取 证书库 的分页数据
     *
     * @param pageSize 分页大小
     * @param pageNum  当前页
     * @return ReturnInfo
     */
    ReturnInfo getCertListByPage(int pageSize, int pageNum);

    /**
     * 获取临时证书库的分页数据
     *
     * @param pageSize 分页大小
     * @param pageNum  当前页 从 1 开始
     * @return ReturnInfo
     */
    ReturnInfo getTmpCertListByPage(int pageSize, int pageNum);


    /**
     * 修改证书文本字段
     *
     * @param certificateTmp 证书对象
     * @return ReturnInfo
     */
    ReturnInfo modifyCertTmp(CertificateTmp certificateTmp);

    /**
     * 给定搜索条件进行搜索, 并以分页的形式返回
     *
     * @param pageSize    分页大小
     * @param pageNum     第几页
     * @param certType    证书类型(模糊匹配)
     * @param name        姓名
     * @param sex         性别
     * @param userId      身份证号
     * @param certId      证书编号
     * @param issueDate   证书颁发时间
     * @param institution 颁发单位
     * @return ReturnInfo
     */
    ReturnInfo getCertListByQuery(int pageSize, int pageNum, String certType, String name, String sex,
                                  String userId, String certId, String issueDate, String institution);


    /**
     * 删除临时数据库中的证书数据
     */
    void deleteMultipleCerts();

    /**
     * 删除证书
     *
     * @param UId 证书唯一 Id
     * @return ReturnInfo
     * @throws CertificateNotFoundException 证书不存在
     */
    ReturnInfo deleteCert(long UId) throws CertificateNotFoundException;

    /**
     * 更新证书
     *
     * @param certificate 证书
     * @return ReturnInfo
     */
    ReturnInfo updateCert(Certificate certificate);

    /**
     * 拷贝证书属性 - util
     *
     * @param dest     目的
     * @param resource 拷贝源
     * @return Certificate
     */
    Certificate copyCert(Certificate dest, Certificate resource);

    /**
     * 单张或多张证书上链
     *
     * @param certUIdList 证书列表
     * @return ReturnInfo
     */
    ReturnInfo upload2chain(List<Long> certUIdList);

    /**
     * 撤销证书（单张）
     *
     * @param certUId 证书 UId
     * @param pwd     当前账户的密码
     * @param reason  撤销原因
     * @return ReturnInfo
     */
    ReturnInfo revokeCert(long certUId, String pwd, String reason) throws WrongPasswordException, CertificateNotFoundException, CertRevokedException;

    /**
     * 分页查询已颁发证书
     *
     * @param pageSize  分页大小
     * @param pageNum   当前分页
     * @param certType  证书类型
     * @param name      姓名
     * @param sex       性别
     * @param userId    身份证号
     * @param certId    证书Id
     * @param issueDate 颁发日期
     * @param certState 证书状态 int 0-未上链 1-上链中 2-已上链 3-已撤销
     * @return ReturnInfo
     */
    ReturnInfo upload2ChainList(int pageSize, int pageNum, String certType, String name, String sex,
                                String userId, String certId, String issueDate, String certState);

    /**
     * 返回某张证书的详细信息
     *
     * @param UId 证书唯一Id
     * @return ReturnInfo
     */
    ReturnInfo getCertDetail(long UId) throws CertificateNotFoundException;

    /**
     * 所有证书上链
     *
     * @return
     */
    ReturnInfo uploadAllCertsToChain();

    /*
     *
     *
     *
     *
     *
     *
     * 与区块链进行交互
     *
     *
     *
     *
     *
     *
     */

    /**
     * 单张证书上链
     */
    ReturnInfo uploadCert2Chain(long certUId) throws CertificateNotFoundException, CertsExistOnChainException;


    /**
     * 查看区块链上的信息
     */
    List<CertOnChain> getCertsOnChain();


    /*
     *
     *
     *
     *
     *
     *
     *
     *
     *
     * Tool
     *
     *
     *
     *
     *
     *
     *
     *
     *
     */

    /**
     * 拼接证书属性用于上链
     *
     * @param cert 证书
     * @return String
     */
    String cert2CertOnChain(Certificate cert);


}
